<?php
/**
 * Facade class for the "Grace Price Bands" modules
 *
 * @access 	public
 * @author 	Rob Locke/Salvatore Borrelli
 * @copyright	ResMania 2011 all rights reserved.
 * @version	1.1
 * @link		http://developer.resmania.com/api
 * @since  	11-2011
 */
class RM_Module_GracePriceBands extends RM_Module implements RM_Prices_Interface, RM_Unit_Copy_Interface, RM_Extras_Interface
{    
    /**
     * Class constants
     */
    const SUMMARY_TYPE = 'Single';
    const EXTRA_DRIVER_AGE = 'Driver Age';
    /**
     * Driver's age range corresponding to last reservation
     */
    private $driverAge;
    
    /**
     * Gets the last reservation driver's age
     * @return the selected age range
     */
    function getDriverAge() {
        return $this->driverAge;
    }
    /**
     * Sets the last reservation driver's age
     * @param driverAge the selected age range
     */
    function setDriverAge($driverAge) {
        $this->driverAge = $driverAge;
    }
    
    function copyInformation(RM_Unit_Row $original, RM_Unit_Row $copy)
    {
        $unitPricesModel = new RM_UnitGracePriceBands();
        $unitPrices = $unitPricesModel->getUnitPrices($original);
        foreach ($unitPrices as $unitPrice) {
            $unitPriceCopyData = $unitPrice->toArray();
            unset($unitPriceCopyData['id']);
            $unitPriceCopyData['unit_id'] = $copy->id;
            $unitPriceCopy = $unitPricesModel->createRow($unitPriceCopyData);
            $unitPriceCopy->save();
        }
        $unitPricesConfigModel = new RM_UnitGracePriceBandsConfig();
        $unitPricesConfigs = $unitPricesConfigModel->getByUnit($original);
        foreach ($unitPricesConfigs as $unitPricesConfig) {
            $unitPricesConfigCopyData = $unitPricesConfig->toArray();
            $unitPricesConfigCopyData['unit_id'] = $copy->id;
            $unitPricesConfigCopy = $unitPricesConfigModel->createRow($unitPricesConfigCopyData);
            $unitPricesConfigCopy->save();
        }
    }

    public function  __construct() {
        $this->name = 'GracePriceBands';
    }

    public function getNode(){
        $std = new stdClass;

        $std->id = $this->name.'_ListJson_NoAjax';
        $std->text = $this->getName();

        $std->iconCls = 'RM_modules_leaf_icon';
        $std->leaf = 'true';
        return $std;
    } 
    /**
     * Calculate the total price for one unit
     *
     * @throw RM_Exception - with message that is going wrong while price calculation
     * @param $information RM_Prices_Information - information object,
     * contains all needed information about unit reservation:
     * unit,
     * start date,
     * end date,
     * number of persons
     * etc.
     *
     * @param bool $byStep - if true, the result will be in array (0 => array('step' => RM_Date, 'price' => float))     
     * @return float
     */
    public function getTotalUnitPrice(RM_Prices_Information $information, $byStep = false) {
        // gets the bands configuration for this unit
        $unitCfgModel = new RM_UnitGracePriceBandsConfig();
        $unit = $information->getUnit();
        $unitId = $unit->id;
        $cfg = $unitCfgModel->fetchByUnit($unitId);
        $settings = (!empty($cfg) ? $cfg->toArray() : array());
        $calculator = new RM_GracePriceBands_Calculator(
            new RM_UnitGracePriceBands(), new RM_GracePriceBands(),
            $settings, RM_Environment::getInstance()->getTranslation(RM_Environment::TRANSLATE_ERRORS)
        );
        return $calculator->getTotalUnitPrice($information, $byStep);
    }
    /**
     * Returns the lowest price of a unit over a given period
     *
     * @param $information RM_Prices_Information - information object,
     * contains all needed information about unit reservation:
     * unit,
     * start date,
     * end date,
     * number of persons
     * etc.
     *
     * @return float
     */
    public function getLowestUnitPrice(RM_Prices_Information $information) {
        $model = new RM_UnitGracePriceBands();
        return $model->getLowestPrice($information);
    }
    /**
     * Return max prices among all units for the one default period for price manager
     * @return float
     */
    public function getTotalHighestPrice() {
        $model = new RM_UnitGracePriceBands();
        return $model->getHighestPrice();
    }
    /**
     * Returns all unit ids that have price in price range in input period
     *
     * @param float $from
     * @param float $to
     * @param RM_Reservation_Period $period
     * @return array array with unit ids
     */    
    public function getByPriceRange($from, $to, RM_Reservation_Period $period = null) {
        $model = new RM_UnitGracePriceBands();
        $rows = $model->getByPriceRange($from, $to, $period);
        $unitIDs = array();
        foreach ($rows as $row) {
            $unitIDs[] = $row->unit_id;
        }
        return $unitIDs;
    }
    /**
     * Returns all unit that have a min stay on this period less than this period
     *
     * @param RM_Reservation_Period $period
     * @return array array with unit ids
     */
    public function getByMinPeriod(RM_Reservation_Period $period) {
        $model = new RM_UnitGracePriceBands();
        return $model->getByMinPeriod($period);
    }
    /**
     * Returns PHP dateformat to present reservation start and end date on the UI
     *
     * @param bool $php - internal PHP date format or UI date format, if true - internal PHP date format
     * @return string
     */
    public function getDateformat($php = false) {

        $model = new RM_GracePriceBandsConfig();

        if ($php) {
            return RM_Config::MYSQL_DATEFORMAT_SHORT;
        }

        $config = new RM_Config;
        return $config->getJSDateformat();
    }
    /**
     * this method returns if the times should be collected for this price module
     *
     * @return boolean
     */
    public function getShowTime(){
        return 1;
    }
    /**
     * Returns the other information associated with this price system.
     *
     * @return array
     */
    public function getOtherInfo(){
        return null;
    }
    /**
     * this method returns a default value for people maximums
     *
     * @return boolean
     */
    public function getPeopleMaximums(){
        return 1;
    }
    /**
     * this method returns a default value for board types
     *
     * @return null
     */
    public function getBoardTypes(){
        return null;
    }

    public function getUnitWithAvailabiltyCheckDisabled(){
        $model = new RM_UnitDailyPricesConfig();
        $rows = $model->fetchUnitsByValue('availablity_check');

        $unitIDs = array();
        foreach ($rows as $row) {
            if ($row->value=="0"){
                $unitIDs[] = (array("id"=>$row->unit_id));
            }
        }
        return $unitIDs;
    }

    /**
     * Module Upgrade routine
     */
    public function upgrade(){

        $moduleViewFolderPath = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','modules',$this->name,'views','user'));
        $mainFolderPath = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','views','user','scripts'));

        // copy the search form panel into place
        $fileSource1 = implode(DIRECTORY_SEPARATOR, array($moduleViewFolderPath.DIRECTORY_SEPARATOR.'Search','gracepricebands_dates_advancedsrch.phtml'));
        $fileDestin1 = implode(DIRECTORY_SEPARATOR, array($mainFolderPath.DIRECTORY_SEPARATOR.'Search'.DIRECTORY_SEPARATOR.'advanced','gracepricebands_dates_advancedsrch.phtml'));
        $renameStatus1 = rename($fileSource1, $fileDestin1);

    }

    /**
    * Install routine
    */
    public function install() {
        parent::install();

        $moduleViewFolderPath = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','modules',$this->name,'views','user'));
        $mainFolderPath = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','views','user','scripts'));

        // copy the search form panel into place
        $fileSource1 = implode(DIRECTORY_SEPARATOR, array($moduleViewFolderPath.DIRECTORY_SEPARATOR.'Search','gracepricebands_dates_advancedsrch.phtml'));
        $fileDestin1 = implode(DIRECTORY_SEPARATOR, array($mainFolderPath.DIRECTORY_SEPARATOR.'Search'.DIRECTORY_SEPARATOR.'advanced','gracepricebands_dates_advancedsrch.phtml'));
        $renameStatus1 = rename($fileSource1, $fileDestin1);
        // copy the summary form panel into place
        $fileSource2 = implode(DIRECTORY_SEPARATOR, array($moduleViewFolderPath.DIRECTORY_SEPARATOR.'Reservations'.DIRECTORY_SEPARATOR.'summary','gracepricebands_driverage_summary.phtml'));
        $fileDestin2 = implode(DIRECTORY_SEPARATOR, array($mainFolderPath.DIRECTORY_SEPARATOR.'Reservations'.DIRECTORY_SEPARATOR.'summary','gracepricebands_driverage_summary.phtml'));
        $renameStatus2 = rename($fileSource2, $fileDestin2);
    }

    /**
     * uninstall routine
     */
    public function uninstall() {
        parent::uninstall();

        $file1 = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','views','user','scripts','Search','advanced','gracepricebands_dates_advancedsrch.phtml'));
        RM_Filesystem::deleteFile($file1);
        $file2 = implode(DIRECTORY_SEPARATOR, array(RM_Environment::getConnector()->getRootPath(),'RM','userdata','views','user','scripts','Reservations','summary','gracepricebands_driverage_summary.phtml'));
        RM_Filesystem::deleteFile($file2);
    }
    
    /**
     * Recalculate all for reservation, after some of the unit details has been changed
     *
     * @abstract
     * @param RM_Reservation_Row $reservation
     * @return bool
     */
    function recalculate(RM_Reservation_Row $reservation)
    {
    }
    /**
     * Returns extra HTML for a summary reservation page to present current system
     *
     * @abstract
     * @param RM_Reservation_Details $detail
     * @return string HTML code to paste
     */
    public function getSummary(RM_Reservation_Details $detail) {
        return null;
    }

    /**
     * Validate selected by user selection
     *
     * @abstract
     * @param Zend_Controller_Request_Abstract $request
     * @return bool
     */
    public function applySelection(Zend_Controller_Request_Abstract $request, RM_Reservation_Details $detail) {
        $driverAge = $request->getParam('gracepricebands_driverage');
        $this->setDriverAge($driverAge);
        return $detail;
    }

    /**
     * Assign extras to reservation
     *
     * @abstract
     * @param RM_Reservation_Details $detail
     * @param RM_Reservation_Details_Row $detailRow
     * @return bool
     */
    public function assign(RM_Reservation_Details $detail, RM_Reservation_Details_Row $detailRow) {
        $driverAge = $this->getDriverAge();
        if (!empty($driverAge)) {
            $resId = $detailRow->reservation_id;
            $resDetailId = $detailRow->id;
            $summaryModel = new RM_ReservationSummary();
            $summaryModel->insert(array(
                'reservation_id'=>$resId,
                'reservation_detail_id' => $resDetailId,
                'type' => self::SUMMARY_TYPE,
                'value' => $driverAge,
                'total_amount' => 0,
                'name' => self::EXTRA_DRIVER_AGE
            ));
        }
    }
}